/* Copyright (c) 2004-2022 peigen.info. All rights reserved. */

package info.peigen.hotpot.common.core.enums;

import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <b>(Symbol)</b>
 *
 * @author Peigen
 * @version 1.0.0
 * @since 2019-05-29
 */
@Getter
@NoArgsConstructor
@AllArgsConstructor
public enum Symbol implements Messageable {
    /** 与和符 */
    AMPERSAND("&", "与和符"),

    /** 波浪字符或代字号 */
    TILDE("~", "波浪字符或代字号"),

    /** 等号 */
    EQUALS("=", "等号"),

    /** 连字符 */
    HYPHEN("-", "连字符"),

    /** 破折号 */
    DASH("–", "破折号"),

    /** 惊叹号 */
    EXCLAMATION("!", "惊叹号"),

    /** 爱特或小老鼠 */
    AT("@", "爱特或小老鼠"),

    /** 井号 */
    NUMBER("#", "井号"),

    /** 美元符 */
    DOLLAR("$", "美元符"),

    /** 百分号 */
    PERCENT("%", "百分号"),

    /** 星号 */
    ASTERISK("*", "星号"),

    /** 脱字符 */
    CARET("^", "脱字符"),

    /** 下划线 */
    UNDERSCORE("_", "下划线"),

    /** 加号 */
    PLUS("+", "加号"),

    /** 减号 */
    MINUS("-", "减号"),

    /** 小于号 */
    LESS_THAN_SIGN("<", "小于号"),

    /** 大于号 */
    GREATER_THAN_SIGN(">", "大于号"),

    /** 句号点 */
    DOT(".", "句号点"),

    /** 逗号 */
    COMMA(",", "逗号"),

    /** 冒号 */
    COLON(":", "冒号"),

    /** 分号 */
    SEMICOLON(";", "分号"),

    /** 问号 */
    QUESTION("?", "问号"),

    /** 斜线 */
    FORWARD_SLASH("/", "斜线"),

    /** 反斜线 */
    BACK_SLASH("\\", "反斜线"),

    /** 竖线 */
    VERTICAL_BAR("|", "竖线"),

    /** 双引号 */
    QUOTATION("\"", "双引号"),

    /** 省略符号 */
    APOSTROPHE("'", "单引号，省略符号"),

    ;

    /** 枚举值 */
    private String code;

    /** 枚举描述 */
    private String message;


    /**
     * 通过枚举<code>code</code>获得枚举
     *
     * @param code code
     *
     * @return Symbol
     */
    public static Symbol getByCode(String code) {
        return Stream.of(values())
                .filter(innerEnum -> StrUtil.equals(code, innerEnum.getCode()))
                .findFirst().orElse(null);
    }

    /**
     * 获取全部枚举
     *
     * @return List<Symbol>
     */
    public static List<Symbol> getAllEnum() {
        return Lists.newArrayList(values());
    }

    /**
     * 获取全部枚举值
     *
     * @return List<String>
     */
    public static List<String> getAllEnumCode() {
        return getAllEnum().stream().map(innerEnum -> innerEnum.getCode()).collect(Collectors.toList());
    }

    /**
     * 通过code获取msg
     *
     * @param code 枚举值
     *
     * @return String
     */
    public static String getMsgByCode(String code) {

        return Optional.ofNullable(code).flatMap(str -> Optional.ofNullable(getByCode(str))
                .map(Symbol::message)).orElse(null);
    }

    /**
     * 获取枚举code
     *
     * @param innerEnum enum
     *
     * @return
     */
    public static String getCode(Symbol innerEnum) {
        return Optional.ofNullable(innerEnum).map(inner -> inner.getCode()).orElse(null);
    }

    /**
     * 实名登记map
     *
     * @return Map
     */
    public static Map<String, String> maps() {

        return Stream.of(values()).collect(Collectors.toMap(Symbol::code, Symbol::message));
    }

    /** @return Returns the code. */
    public String getCode() {
        return code;
    }

    /** @return Returns the message. */
    public String getMessage() {
        return message;
    }

    /** @return Returns the code. */
    @Override
    public String code() {
        return code;
    }

    /** @return Returns the message. */
    @Override
    public String message() {
        return message;
    }

}